﻿using System;
using Microsoft.Xna.Framework;
using SpaceGame.Gameplay.AI.Pathfinding;
using SpaceGame.Util;

namespace SpaceGame.Simulation
{
    public static class WallFactory
    {

        /// <summary>
        /// Create a new array of walls based on the current world rules.
        /// </summary>
        /// <param name="wallStyle">specify style</param>
        /// <param name="safeDimensions">specify bounding dimension</param>
        /// <param name="navigationMesh">Returna static navigation mesh based on these set of walls.</param>
        /// <returns></returns>
        public static Vector2[] CreateWalls(WallStyle wallStyle, Rectangle safeDimensions, out NavigationMesh navigationMesh)
        {
            Vector2[] walls;
            navigationMesh = new NavigationMesh();
            
            switch (wallStyle)
            {
                case WallStyle.None:
                    walls = new Vector2[8];
                    break;
                case WallStyle.One:
                    walls = new Vector2[10];
                    break;
                case WallStyle.Two:
                    walls = new Vector2[12];
                    break;
                case WallStyle.Three:
                    walls = new Vector2[14];
                    break;

                default:
                    throw new ArgumentException("this factory does not know about this wall style.");
            }

            // The outer boundaries
            walls[0] = new Vector2(safeDimensions.X, safeDimensions.Y);
            walls[1] = new Vector2(safeDimensions.X, safeDimensions.Y + safeDimensions.Height);

            walls[2] = new Vector2(safeDimensions.X + safeDimensions.Width, safeDimensions.Y);
            walls[3] = new Vector2(safeDimensions.X + safeDimensions.Width, safeDimensions.Y + safeDimensions.Height);

            walls[4] = new Vector2(safeDimensions.X, safeDimensions.Y);
            walls[5] = new Vector2(safeDimensions.X + safeDimensions.Width, safeDimensions.Y);

            walls[6] = new Vector2(safeDimensions.X, safeDimensions.Y + safeDimensions.Height);
            walls[7] = new Vector2(safeDimensions.X + safeDimensions.Width, safeDimensions.Y + safeDimensions.Height);

            int quarterX = safeDimensions.Width / 4;
            int quarterY = safeDimensions.Height / 4;
            int halfY = safeDimensions.Height / 2;

            switch (WorldRules.WallStyle)
            {
                case WallStyle.One:
                    // Cross line
                    walls[8] = new Vector2(safeDimensions.X + quarterX, safeDimensions.Y + halfY);
                    walls[9] = new Vector2(safeDimensions.X + 3 * quarterX, safeDimensions.Y + halfY);

                    //manually creating navmesh
                    MeshNode n1 = new MeshNode(new Polygon(walls[0], walls[8], walls[1]));
                    MeshNode n2 = new MeshNode(new Polygon(walls[0], walls[2], walls[9], walls[8]));
                    MeshNode n3 = new MeshNode(new Polygon(walls[9], walls[2], walls[7]));
                    MeshNode n4 = new MeshNode(new Polygon(walls[6], walls[8], walls[9], walls[7]));

                    navigationMesh.AddNodes(n1, n2, n3, n4);
                    navigationMesh.AddConnection(n1, n2);
                    navigationMesh.AddConnection(n2, n3);
                    navigationMesh.AddConnection(n3, n4);
                    navigationMesh.AddConnection(n1, n4);
                    

                    break;
                case WallStyle.Two:
                    walls[8] = new Vector2(safeDimensions.X + quarterX, safeDimensions.Y + quarterY);
                    walls[9] = new Vector2(safeDimensions.X + quarterX, safeDimensions.Y + 3 * quarterY);
                    walls[10] = new Vector2(safeDimensions.X + 3 * quarterX, safeDimensions.Y + quarterY);
                    walls[11] = new Vector2(safeDimensions.X + 3 * quarterX, safeDimensions.Y + 3 * quarterY);

                    //manually creating navmesh
                    MeshNode w2_n1 = new MeshNode(new Polygon(walls[0], walls[8], walls[9], walls[1]));
                    MeshNode w2_n2 = new MeshNode(new Polygon(walls[0], walls[2], walls[10], walls[8]));
                    MeshNode w2_n3 = new MeshNode(new Polygon(walls[10], walls[2], walls[3], walls[11]));
                    MeshNode w2_n4 = new MeshNode(new Polygon(walls[1], walls[9], walls[11], walls[3]));
                    MeshNode w2_n5 = new MeshNode(new Polygon(walls[8], walls[10], walls[11], walls[9]));

                    navigationMesh.AddNodes(w2_n1, w2_n2, w2_n3, w2_n4, w2_n5);
                    navigationMesh.AddConnection(w2_n1, w2_n2);
                    navigationMesh.AddConnection(w2_n2, w2_n5);
                    navigationMesh.AddConnection(w2_n2, w2_n3);
                    navigationMesh.AddConnection(w2_n3, w2_n4);
                    navigationMesh.AddConnection(w2_n4, w2_n1);
                    navigationMesh.AddConnection(w2_n4, w2_n5);
                    

                    break;
                case WallStyle.Three:
                    walls[8] = new Vector2(safeDimensions.X + quarterX, safeDimensions.Y + quarterY);
                    walls[9] = new Vector2(safeDimensions.X + quarterX, safeDimensions.Y + 3 * quarterY);
                    walls[10] = new Vector2(safeDimensions.X + 3 * quarterX, safeDimensions.Y + quarterY);
                    walls[11] = new Vector2(safeDimensions.X + 3 * quarterX, safeDimensions.Y + 3 * quarterY);
                    // Cross line
                    walls[12] = new Vector2(safeDimensions.X + quarterX, safeDimensions.Y + halfY);
                    walls[13] = new Vector2(safeDimensions.X + 3 * quarterX, safeDimensions.Y + halfY);

                    //manually creating navmesh
                    MeshNode w3_n1 = new MeshNode(new Polygon(walls[0], walls[8], walls[9], walls[1]));
                    MeshNode w3_n2 = new MeshNode(new Polygon(walls[0], walls[2], walls[10], walls[8]));
                    MeshNode w3_n3 = new MeshNode(new Polygon(walls[10], walls[2], walls[3], walls[11]));
                    MeshNode w3_n4 = new MeshNode(new Polygon(walls[1], walls[9], walls[11], walls[3]));

                    MeshNode w3_n5 = new MeshNode(new Polygon(walls[8], walls[10], walls[13], walls[12]));
                    MeshNode w3_n6 = new MeshNode(new Polygon(walls[12], walls[13], walls[11], walls[9]));

                    navigationMesh.AddNodes(w3_n1, w3_n2, w3_n3, w3_n4, w3_n5, w3_n6);
                    navigationMesh.AddConnection(w3_n1, w3_n2);
                    navigationMesh.AddConnection(w3_n2, w3_n5);
                    navigationMesh.AddConnection(w3_n2, w3_n3);
                    navigationMesh.AddConnection(w3_n3, w3_n4);
                    navigationMesh.AddConnection(w3_n4, w3_n1);
                    navigationMesh.AddConnection(w3_n4, w3_n6);


                   
                    break;
            }


            return walls;
        }

    }
}
